package com.sinodata.bsm.cicp.collector.weblogic9;

import java.util.ArrayList;
import java.util.List;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;

import org.apache.log4j.Logger;

import com.sinodata.bsm.cicp.collector.Collector;
import com.sinodata.bsm.cicp.exception.CollectorException;
import com.sinodata.bsm.cicp.util.JmxUtil;
import com.sinodata.bsm.common.vo.ResPropertyValue;

/**
 * 
 * <p>
 * Description: weblogic 集群采集程序
 * </p>
 *
 * @author liulibo
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * 2012-12-26 AM 10:04:36   liulibo        1.0         To create
 * </p>
 *
 * @since 
 * @see
 */
public class ClusterCollector extends Collector {

    private static final Logger logger = Logger.getLogger(ClusterCollector.class);

    @Override
    public List<ResPropertyValue> collect(String ip) throws CollectorException {
        List<ResPropertyValue> values = new ArrayList<ResPropertyValue>();
        String clusterName = this.getParamMap().get("ClusterName").trim();
        String port = this.getParamMap().get("port").trim();
        String[] propMetas = getPropMeta();
        ResPropertyValue propertyValueX = new ResPropertyValue();
        ResPropertyValue.PropValue[] propValues = new ResPropertyValue.PropValue[propMetas.length];
        ObjectName service;
        JMXConnector connector = null;
        MBeanServerConnection connection = null;
        try {
            connector = JmxUtil.getConnection(ip, Integer.valueOf(port));
            connection = connector.getMBeanServerConnection();
            service = new ObjectName("com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime" + ".DomainRuntimeServiceMBean");
            String attributeNames[] = new String[] { "Name", "ClusterAddress", "MigrationBasis", "DefaultLoadAlgorithm", "ClusterType", "Servers" };
            Object domainConfiguration = connection.getAttribute(service, "DomainConfiguration");
            ObjectName[] clusters = (ObjectName[]) connection.getAttribute((ObjectName) domainConfiguration, "Clusters");
            for (ObjectName objectName : clusters) {
                Object attrValues[] = null;
                attrValues = JmxUtil.getAttribute(connection, objectName, attributeNames);
                if (attrValues[0].toString().equals(clusterName)) {
                    for (int i = 1; i < attrValues.length; i++) {
                        if (((attrValues[i] != null)) && (attrValues[i] instanceof ObjectName[])) {
                            StringBuffer sb = new StringBuffer();
                            for (ObjectName object : (ObjectName[]) attrValues[i]) {
                                String name = object.getKeyProperty("Name");
                                sb.append(name + ",");
                            }

                            if (sb.length() > 0) {
                                sb.deleteCharAt(sb.length() - 1);
                            }

                            propValues[i - 1] = ResPropertyValue.createPropValue(sb.toString(), propMetas[i - 1]);
                            propValues[i] = ResPropertyValue.createPropValue(String.valueOf(((ObjectName[]) attrValues[i]).length), propMetas[i]);
                        } else {
                            propValues[i - 1] = ResPropertyValue.createPropValue(attrValues[i] == null ? "" : attrValues[i].toString(), propMetas[i - 1]);
                        }
                    }
                }
            }

            //weblogic9没有下面两个MBean，weblogic10有
            try {
                String attNames[] = new String[] { "Name", "ClusterMessagingMode", "ClusterBroadcastChannel" };
                ObjectName[] clus = (ObjectName[]) connection.getAttribute((ObjectName) domainConfiguration, "Clusters");
                for (ObjectName objectName : clus) {
                    Object attrValues[] = null;
                    attrValues = JmxUtil.getAttribute(connection, objectName, attNames);
                    if (attrValues[0].toString().equals(clusterName)) {
                        for (int i = 1; i < attrValues.length; i++) {
                            if (((attrValues[i] != null)) && (attrValues[i] instanceof ObjectName[])) {
                                StringBuffer sb = new StringBuffer();
                                for (ObjectName object : (ObjectName[]) attrValues[i]) {
                                    String name = object.getKeyProperty("Name");
                                    sb.append(name + ",");
                                }

                                if (sb.length() > 0) {
                                    sb.deleteCharAt(sb.length() - 1);
                                }

                                propValues[i + 5] = ResPropertyValue.createPropValue(sb.toString(), propMetas[i + 5]);
                            } else {
                                propValues[i + 5] = ResPropertyValue.createPropValue(attrValues[i] == null ? "" : attrValues[i].toString(), propMetas[i + 5]);
                            }

                        }
                    }
                }
            } catch (Exception e) {
                logger.info("weblogic 9 no ClusterMessagingMode/ClusterBroadcastChannel MBean!");
                propValues[6] = ResPropertyValue.createPropValue("N/A", propMetas[6]);
                propValues[7] = ResPropertyValue.createPropValue("N/A", propMetas[7]);
            }

            ObjectName[] serverRuntimes = (ObjectName[]) connection.getAttribute(service, "ServerRuntimes");
            String test[] = new String[] { "AliveServerCount", "ServerNames" };
            for (ObjectName objectName2 : serverRuntimes) {
                Object clusterRuntime = connection.getAttribute(objectName2, "ClusterRuntime");
                if (clusterRuntime != null) {
                    String name = ((ObjectName) clusterRuntime).getKeyProperty("Name");
                    if (name.equals(clusterName)) {
                        Object attrValues[] = null;
                        attrValues = JmxUtil.getAttribute(connection, (ObjectName) clusterRuntime, test);
                        for (int i = 0; i < attrValues.length; i++) {
                            if ((attrValues[i] != null) && (attrValues[i] instanceof String[])) {
                                StringBuffer sb = new StringBuffer();
                                for (String object : (String[]) attrValues[i]) {
                                    sb.append(object.toString() + " ");
                                }
                                propValues[i + 8] = ResPropertyValue.createPropValue(sb.toString(), propMetas[i + 8]);
                            } else {
                                propValues[i + 8] = ResPropertyValue.createPropValue(attrValues[i] == null ? "" : attrValues[i].toString(), propMetas[i + 8]);
                            }
                        }
                    }
                }
            }
            //采集不到值的时候给数量为0服务名为空 写到循环里是错误的
            if (propValues[8] == null) {
                propValues[8] = ResPropertyValue.createPropValue("0", propMetas[8]);
            }
            if (propValues[9] == null) {
                propValues[9] = ResPropertyValue.createPropValue("", propMetas[9]);
            }
        } catch (Exception e) {
            logger.error("failed to collect by ClusterCollector", e);
            throw new CollectorException(e);
        } finally {
            JmxUtil.closeConnector(connector);
        }
        propertyValueX.setValues(propValues);
        values.add(propertyValueX);
        return values;
    }

    @Override
    public String[] getParamMeta() {
        return new String[] { "ClusterName", "port" };
    }

    @Override
    public String[] getPropMeta() {
        //return new String[] { "ClusterAddress", "MigrationBasis", "DefaultLoadAlgorithm", "ClusterType", "ServerNameList", "Servers", "ClusterMessagingMode", "ClusterBroadcastChannel", "AliveServerCount", "ServerNames" };
        return new String[] { "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10" };
    }
}
